uefi 安装启动
·
Secure Boot 的签名链(PK/KEK/DB) 中的各自的作用?
结合完整的 Secure Boot 启动链(shim → grub → kernel) 进行详细的解释
信任链的根源 (OEM/固件)
-
首先,UEFI 安全启动的信任链始于固件(BIOS/UEFI)。固件中预先存储了三个关键的密钥数据库:
-
平台密钥 (PK - Platform Key): 最高级的密钥,用于签署 KEK 的更新。由 PC 制造商 (OEM) 负责管理。
-
密钥交换密钥 (KEK - Key Exchange Key): 用于签署签名数据库 (db) 和禁止签名数据库 (dbx) 的更新。
-
签名数据库 (db - Signature Database): 包含了被允许执行的操作系统引导加载程序、驱动程序等组件的公钥或证书。
-
初始状态下,这个 db 数据库中通常包含:
-
OEM 自己的证书: 用于验证固件更新和 OEM 自己的工具。
-
Microsoft Corporation UEFI CA 证书: 允许启动所有由微软签名的组件,包括 Windows 启动管理器以及由微软服务签名的第三方引导加载程序。
UEFI 固件内部存有四类关键数据库:
| 名称 | 类型 | 主要作用 | 由谁管理 |
|---|---|---|---|
| PK(Platform Key) | 公开证书 + 私钥在厂商手上 | 管理平台最顶层权限(用来更新 KEK) | OEM(华硕、联想等) |
| KEK(Key Exchange Key) | 公开证书 | 用来更新 DB / DBX | OEM、Microsoft |
| DB(Allowed Signatures)允许列表 | 证书 + Hash | 允许启动的 EFI 程序的签名 | Microsoft(多数 PC),OEM,用户 |
| DBX(Forbidden Signatures)禁止列表 | 证书 + Hash | 被吊销/恶意的 EFI 程序摘要 | Microsoft |
Secure Boot 的工作原则:UEFI 只允许 DB 中签名的文件启动,禁止 DBX 中的文件。
- UEFI 会从 DB/DBX 中取证书来验证 shim 的签名
- shim.efi 验证 grubx64.efi(第二级验证)
- shim 内置了一个 shim-own certificate (MOK)
- → 是从 Linux 发行版(或用户)生成的
- → 不需要微软参与
- 所以 shim 的验证过程:
- shim 内的 MOK 列表(Machine Owner Keys) ↓ 验证 grub 是否被 MOK 签名 grub 才能启动
- shim 的最大用途:让 Linux 自己管理信任链,而不依赖微软。
- 用户也可以加入自己的 MOK(mokutil --import)这样用户可以签:
- grub
- kernel
- initrd
- 甚至自己写的 EFI 程序
- shim 内置了一个 shim-own certificate (MOK)
- grubx64.efi 验证 Linux kernel(第三级验证)
- 使用 shim 提供的验证接口(shim_lock)
- ↓ 验证 kernel 是否被 MOK(DB)签名
- kernel 才能加载
- 使用 shim 提供的验证接口(shim_lock)
- 通常:
- 在 Ubuntu / Debian,kernel 已经用 Canonical 的私钥签名(内置在 shim MOK 内)
- 在 Fedora,kernel 用 Red Hat 的私钥签名
- 所以 grub加载内核时会调用 shim 的验证函数:
- verify_pe_signature()
- 决定内核是否可信。
微软的角色:商业公司的“代理签名”
- 微软确实在为其他商业公司签名方面扮演了核心角色,但不是直接负责。
- 机制: 微软提供了一个 UEFI CA (Certificate Authority) 证书,这个证书被全球几乎所有 OEM 预装在了 UEFI 固件的 db 数据库中。
- 服务: 许多第三方操作系统供应商或硬件/驱动程序制造商(如主流的 Linux 发行版,如 Canonical/Ubuntu、Red Hat 等)为了让他们的启动文件能在一台开启了安全启动的 Windows 电脑上运行,会向微软的 硬件仪表板(Hardware Dashboard) 提交他们的启动文件(例如 Linux 的 shim.efi)。
- 签名: 微软使用自己的 Microsoft UEFI CA 证书的私钥,为这些第三方文件进行数字签名。
- 结果: 固件检查启动文件时,发现它是由 Microsoft UEFI CA 签名的,而这个 CA 证书在 db 数据库中是被信任的,因此允许启动。
自己签名 Secure Boot 的实际流程(完整步骤)
下面是 Linux 下常见的方式(OpenSSL + sbsigntools):
① 生成三套密钥(PK/KEK/DB)
openssl req -new -x509 -newkey rsa:2048 -sha256 -keyout PK.key -out PK.crt -subj "/CN=Custom PK/" -days 3650
openssl req -new -x509 -newkey rsa:2048 -sha256 -keyout KEK.key -out KEK.crt -subj "/CN=Custom KEK/" -days 3650
openssl req -new -x509 -newkey rsa:2048 -sha256 -keyout DB.key -out DB.crt -subj "/CN=Custom DB/" -days 3650
② 生成 UEFI 可识别的 .auth 文件
cert-to-efi-sig-list -g "$(uuidgen)" PK.crt PK.esl
sign-efi-sig-list -k PK.key -c PK.crt PK PK.esl PK.auth
KEK/DB 同理。
③ 进入 BIOS,切换到 Custom Secure Boot
大多数设备 BIOS 中选择:
Secure Boot → Custom Mode
然后可以导入你的 PK.auth, KEK.auth, DB.auth
④ 使用你的 DB 私钥签名引导程序
例如对 GRUB2 EFI 文件签名:
sbsign --key DB.key --cert DB.crt --output grubx64.efi grubx64.efi
然后用这个签名过的 grubx64.efi 启动即可。